angular.module('mustache.services', [])
	.factory('unit', function(){
		var wait=60;
		return {
			sendSmsTimer: function(ele){
				if (wait == 0) {
					ele.removeAttr('disabled').text("重新获取验证码");
					wait = 60;
				} else {
					ele.attr('disabled', 'disabled').text(wait + "秒后重发验证码");
					wait--;
					setTimeout(function(){this.sendSmsTimer(ele)}, 1000)
				}
			},
			isEmptyObject: function(e){
				if(angular.isUndefined(e) || e === null){
					return true;
				}else{
					var t;
					for (t in e)
						return !true;
					return !false;
				}
			},
			in_array: function(search, array) {
				for(var i in array){
					if(array[i].toString() == search) return true;
				}
				return false;
			},
			is_array: function (value) {
				return value &&
					typeof value === 'object' &&
					typeof value.length === 'number' &&
					typeof value.splice === 'function' &&
					!(value.propertyIsEnumerable('length'));
			}
		}
	})
	.factory('ngSwal', function(unit){
		var defaults = {
			allowOutsideClick: false,		// 如果设置为“true”，用户可以通过点击警告框以外的区域关闭警告框。
			confirmButtonColor: "#DD6B55",	// 该参数用来改变确认按钮的背景颜色（必须是一个HEX值）。
			confirmButtonText: "确定",		// 该参数用来改变确认按钮上的文字。如果设置为"true"，那么确认按钮将自动将"Confirm"替换为"OK"。
			type: 'info',					// 窗口的类型。有4种类型的图标动画："warning", "error", "success" 和 "info".可以将它放在"type"数组或通过第三个参数传递。
			title: null,					// 窗口的名称。可以通过对象的"title"属性或第一个参数进行传递。
			text: null,						// 窗口的描述。可以通过对象的"text"属性或第二个参数进行传递。
			showCancelButton: false,		// 如果设置为“true”，“cancel”按钮将显示，点击可以关闭警告框。
			showConfirmButton: true,		// 如果设置为“false”，“Confirm”按钮将不显示。
			cancelButtonText: '取消',		// 该参数用来改变取消按钮的文字。
			closeOnConfirm: true,			// 如果希望以后点击了确认按钮后模态窗口仍然保留就设置为"false"。该参数在其他SweetAlert触发确认按钮事件时十分有用。
			timer: null						// 警告框自动关闭的时间。单位是ms。
		}
		function getTitle(type, title){
			if(angular.isUndefined(title) || title === null){
				switch(type){
					case 'success':
						return 'APP操作成功！';
					case 'error':
						return 'APP操作失败！';
					case 'warning':
						return 'APP操作警告！';
					case 'info':
						return 'APP操作提示！';
				}
			}else{
				return title;
			}
		}
		return {
			alert: function(param, callback){
				var config = {}
				config.type = (unit.isEmptyObject(param.type))?'success':param.type.toLowerCase();
				config.title = getTitle(config.type, param.title)
				swal(angular.extend(defaults, param, config), function(){
					if(typeof(callback) == 'function') callback();
				});
			},
			confirm: function(param, callback_ok, callback_cancel){
				var config = {}
				config.type = (unit.isEmptyObject(param.type))?'warning':param.type.toLowerCase();
				config.title = getTitle(config.type, param.title);
				config.showCancelButton = true;
				swal(angular.extend(defaults, param, config), function(isConfirm){
					if (isConfirm) {
						if(typeof(callback_ok) == 'function') callback_ok();
					}else{
						if(typeof(callback_cancel) == 'function') callback_cancel();
					}
				});
			},
			progress: function(param){
				var config = {
					type: 'info',
					html: true,
					title: getTitle('info'),
					text: '<h5 style="color: #797979">正在 <span class="progressText">'+param.text+'</span> 请等待！</h5><div class = "progress progress-striped active">' +
					'<div class = "progress-bar progress-bar-success" role="progressbar" style="width: '+param.width+'%;"></div></div>',
					showLoaderOnConfirm: true,
				};
				swal(angular.extend(defaults, config));
				swal.disableButtons();
			},
            prompt: function (param, callback) {
				var config ={}
                config.type = (unit.isEmptyObject(param.type))?'input':param.type.toLowerCase();
                config.showCancelButton = true;
                config.closeOnConfirm= false;
                config.disableButtonsOnConfirm = true;
                config.animation = "slide-from-top";
                swal(angular.extend(defaults, config, param), function(inputValue){
                	if(inputValue) if(typeof(callback) == 'function') callback(inputValue);
                });
            },
			close: function(){
				swal.close();
			},
			enableButtons: function(){
				swal.enableButtons();
			},
			disableButtons: function(){
				swal.disableButtons();
			}
		}
	})
	.factory('imgPickerService', function($ionicActionSheet, $cordovaCamera, $cordovaBarcodeScanner, $cordovaFileTransfer, $state, unit, configs, ngSwal){
		var Camera = {
			DestinationType:{
				DATA_URL : 0,   //返回Base64编码字符串的图像数据
				FILE_URI : 1    //返回图像文件的URI
			},
			PictureSourceType: {
				PHOTOLIBRARY : 0,
				CAMERA : 1,
				SAVEDPHOTOALBUM : 2
			},
			EncodingType:{
				JPEG : 0,       // 返回JPEG格式图片
				PNG : 1         // 返回PNG格式图片
			},
			PopoverArrowDirection: {
				ARROW_UP: 1,
				ARROW_DOWN: 2,
				ARROW_LEFT: 4,
				ARROW_RIGHT: 8,
				ARROW_ANY: 15
			}
		}
		var defaults = {
			quality: 80,                                           //存储图像的质量，范围是[0,100]。
			destinationType: Camera.DestinationType.FILE_URI,       //选择返回数据的格式
			sourceType: Camera.PictureSourceType.CAMERA,            //设定图片来源。
			allowEdit: true,                                        //在选择图片进行操作之前允许对其进行简单编辑。
			encodingType: Camera.EncodingType.JPEG,                 //选择返回图像文件的编码方式
			targetWidth: 800,                                       //以像素为单位的图像缩放宽度，必须和targetHeight同时使用。
			targetHeight: 600,                                      //以像素为单位的图像缩放高度，必须和targetWidth同时使用。
			popoverOptions: Camera.PopoverArrowDirection.ARROW_UP,  //iOS设备弹出框的位置
			saveToPhotoAlbum: false,                                //保存进手机相册
			mediaType: 0,   //可选媒体类型：圖片=0，只允许选择图片將返回指定DestinationType的参数。 視頻格式=1，允许选择视频，最终返回 FILE_URI。ALLMEDIA= 2，允许所有媒体类型的选择。
			cameraDirection: 0,                                     //枪后摄像头类型：Back= 0,Front-facing = 1
			correctOrientation:true                                 // 设置摄像机拍摄的图像是否为正确的方向
		};
		function sheet(callback){
			$ionicActionSheet.show({
				buttons: [
					{text: '拍照'},
					{text: '从相册选择'}
				],
				titleText: '选择照片',
				cancelText: '取消',
				cancel: function(){
				},
				buttonClicked: function(index){
					if(index == 0){
						defaults.sourceType = Camera.PictureSourceType.CAMERA;
					}else if(index == 1){
						defaults.sourceType = Camera.PictureSourceType.PHOTOLIBRARY;
					}
					if(typeof(callback) == 'function') callback(defaults);
					return true;
				}
			});
		}
		return {
			headimg: function(callback){
				sheet(function(defaults){
					var options = {
						quality: 75,
						cameraDirection: 1,
						targetWidth: 128,
						targetHeight: 128
					}
					$cordovaCamera.getPicture(angular.extend(defaults, options)).then(
						function (imageUrl) {
							if(typeof(callback) == 'function') callback(imageUrl);
						}, function (err) {
							ngSwal.alert({title: '获取摄像机出错啦!', text: err.message, type: 'error'},
								function(){ $state.go('app.home'); });
						}
					);
				});
			},
			camera: function(callback){
				var options = {
					quality: 85,
					allowEdit:false,
					targetWidth: 1200,
					targetHeight: 900
				}
				$cordovaCamera.getPicture(angular.extend(defaults, options)).then(
					function (imageUrl) {
						if(typeof(callback) == 'function') callback(imageUrl);
					}, function (err) {
						ngSwal.alert({title: '获取摄像机出错啦!', text: err.message, type: 'error'},
							function(){ $state.go('app.home'); });
					}
				);
			},
			photo: function(callback){
				sheet(function(defaults){
					$cordovaCamera.getPicture(defaults).then(
						function (imageUrl) {
							if(typeof(callback) == 'function') callback(imageUrl);
						}, function (err) {
							ngSwal.alert({title: '获取照片出错啦!', text: err.message, type: 'error'},
								function(){ $state.go('app.home'); });
						}
					);
				});
			},
			upload: function(param, callback){
				document.addEventListener('deviceready', function () {
					$cordovaFileTransfer.upload(configs.restful_url + '/File/uploadPicture.html', param, {}).then(
						function (result) {
							var response = (result.response)?eval('(' + result.response + ')'):null;
							response.type = 'success';
							if(typeof(callback) == 'function') callback(response);
						}, function (error) {
							error.type = error;
							if(typeof(callback) == 'function') callback(error);
							ngSwal.alert({title: '图片上传出错啦!', text: error.info, type: 'error'},
								function(){ $state.go('app.home'); });
						}, function (progress) {
							var width = Math.floor(parseInt(progress.loaded) / parseInt(progress.total) * 10000)/100;
							jq('div.showSweetAlert').find('div.progress-bar').css('width', width+'%');
						}
					);
				}, false);
			},
			uploads: function(param, text, callback){
				document.addEventListener('deviceready', function(){
					var uploads = function(targetPath, num, response){
						$cordovaFileTransfer.upload(configs.restful_url + '/File/uploadPicture.html', targetPath[num], {}).then(
							function (result) {
								++num;
								response.push((result.response)?eval('(' + result.response + ')'):null);
								jq('div.showSweetAlert').find('span.progressText').text(text + '（' + (num+1) + '/' + targetPath.length +'）');
								jq('div.showSweetAlert').find('div.progress-bar').css('width', '0%');
								if(num < targetPath.length){
									uploads(targetPath, num, response);
								}else{
									ngSwal.close();
									if(typeof(callback) == 'function') callback(response);
								}
							}, function (error) {
								ngSwal.alert({title: '图片上传出错啦!', text: error.info, type: 'error'},
									function(){ $state.go('app.home'); });
							}, function (progress) {
								var width = Math.floor(parseInt(progress.loaded) / parseInt(progress.total) * 10000)/100;
								jq('div.showSweetAlert').find('div.progress-bar').css('width', width+'%');
							}
						);
					}
					if(unit.isEmptyObject(param)){
						ngSwal.alert({text: '没有指定需要上传的图片', type: 'error'});
					}else{
						if(typeof param == 'string')
							var targetPath = new Array(param);
						else
							var targetPath = param;
						ngSwal.progress({text: text + '（1/' + targetPath.length +'）', width: 0});
						uploads(targetPath, 0, []);
					}
				}, false);
			},
			scanQR: function(callback){
				$cordovaBarcodeScanner
					.scan()
					.then(function(barcodeData) {
						if(barcodeData.format == 'QR_CODE' && barcodeData.cancelled == 0){
							if(typeof(callback) == 'function') callback(barcodeData.text);
						}
					}, function(error) {
						ngSwal.alert({title: '扫描二维码出错啦!', text: err.message, type: 'error'},
							function(){ $state.go('app.home'); });
					});
			}
		}
	})
	.factory('xhr', function($http, $ionicLoading, $window, $state, $cordovaDevice, $cordovaSQLite, $q, configs, unit, ngSwal){
		var deferred = $q.defer();
		return {
			sqlite: function (param) {
				var field = new Array;
				var data = new Array;
				var where = new Array;
				var val = new Array;
				if(!unit.isEmptyObject(param.data)){
					for(var i in param.data){
						field.push(i + ' = ?');
						data.push(param.data[i]);
					}
				}
				if(!unit.isEmptyObject(param.where)){
					for(var i in param.where){
						where.push(i + ' = ?');
						val.push(param.where[i]);
					}
				}
				var value = new Array;
				for(var i=0; i<field.length; i++){
					value.push('?');
				}
				if(navigator.userAgent.match(/(iPhone|iPod|Android|ios)/i)){
					var db = null;
					document.addEventListener('deviceready', function() {
						db = window.sqlitePlugin.openDatabase({name: configs.db_name, location: 'default'});
						if(param.type == 'addAll') {
							db.transaction(function(tx){
								angular.forEach(param.data, function (obj) {
									tx.executeSql('Insert INTO ' + param.table + ' VALUES (' + value.split(', ') + ')', obj)
								})
							}), function (error) {
								console.log('Transaction ERROR: ' + error.message);
								deferred.reject(error);
							}, function () {
								console.log('Populated database OK');
							}
						}else if(param.type = 'createTable'){
							function _create_table(table, data){
								db.transaction(function(tx){
									for(var t in table){
										var i = 1;
										var sql = 'CREATE TABLE IF NOT EXISTS ' + t + '(';
										for(var p in table[t]){
											sql += '`'+p+'` ';
											if(table[t][p].type = 'key'){
												sql += 'INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT';
											}else{
												sql =+ table[t][p].type;
												if(table[t][p].null) sql += ' NOT NULL';
												if(!angular.isUndefined(table[t][p].default)){
													if(table[t][p].default === null) sql += ' DEFAULT NULL';
													else sql += ' DEFAULT "'+ table[t][p].default + '"';
												}
											}
											i++;
											if(table[t][p].length != i) sql += ',';
										}
										tx.executeSql(sql + ')');
										angular.forEach(data[t], function(obj){
											var key = new Array;
											var values = new Array;
											for(var k in obj){
												key.push('?');
												values.push(obj[k]);
											}
											tx.executeSql('INSERT INTO '+t +' VALUES (' + key.split(', ') +')', values);
										})
									}
								}, function(error){
									console.log('Transaction ERROR: ' + error.message);
									deferred.reject(error);
								}, function(){
									console.log('Populated database OK');
								});
							}
							if(unit.is_array(param.table))
								for(var p in param.table){
									_create_table(param.table[p], param.data[p]);
								}
							else
								_create_table(param.table, param.data);
						}else{
							switch (param.type){
								case 'add':
									db.executeSql('INSERT INTO '+ param.table +' VALUES (' + value.split(', ') +')', data, function(tx, result){
										console.log('Insert Into '+param.table+' OK!');
										deferred.resolve(result);
									}, function(error){
										console.log('Insert Into '+param.table+' Error: '.error.message);
										deferred.reject(error);
									});
									break;
								case 'save':
									db.executeSql('UPDATE '+param.table+' SET '+field.split(', ')+' WHERE '+where, angular.extend(data, val), function(tx, result){
										console.log('UPDATE '+param.table+' OK!');
										deferred.resolve(result);
									}, function(error){
										console.log('UPDATE '+param.table+' Error: '.error.message);
										deferred.reject(error);
									});
									break;
								case 'del':
									db.executeSql('DELETE FROM ' + param.table + ' WHERE '+ where, val, function(tx, result){
										console.log('DELETE FROM '+param.table+' OK!');
										deferred.resolve(result);
									}, function(error){
										console.log('DELETE FROM '+param.table+' Error: '.error.message);
										deferred.reject(error);
									});
									break;
								case 'find':
									var mySelect = (where.length > 0)?' WHERE '+where:'';
									db.executeSql('SELECT * FROM ' + param.table + mySelect + ' LIMIT 1', val, function(tx, result){
										console.log('FIND FROM '+param.table+' OK!');
										deferred.resolve(result);
									}, function(error){
										console.log('FIND FROM '+param.table+' Error: '.error.message);
										deferred.reject(error);
									});
									break;
								default:
									var mySelect = (where.length > 0)?' WHERE '+where:'';
									db.executeSql('SELECT * FROM ' + param.table + mySelect, val, function(tx, result){
										console.log('FIND FROM '+param.table+' OK!');
										deferred.resolve(result);
									}, function(error){
										console.log('FIND FROM '+param.table+' Error: '.error.message);
										deferred.reject(error);
									});
							}
						}
					});
				}else{
					var http = new XMLHttpRequest();
					http.open('GET', configs.db_name, true);
					http.responseType = 'arraybuffer';
					http.onload = function(e) {
						var uInt8Array = new Uint8Array(this.response);
						var db = new SQL.Database(uInt8Array);
						var sqlite = db.exec('SELECT * FROM '+param.table);
						switch (param.type){
							case 'add':
								sqlite = db.exec('INSERT INTO '+ param.table +' VALUES (' + value.splice(', ') +')', data)
								break;
							case 'save':
								sqlite = db.exec('UPDATE '+ param.table +' SET ' + field.split(', ') + ' WHERE ' + where, angular.extend(data, val));
								break;
							case 'del':
								sqlite = db.exec('DELETE FROM ' + param.table + ' WHERE '+ where, val);
								break;
							case 'find':
								if(where.length > 0)
									sqlite = db.exec('SELECT * FROM '+param.table+' WHERE ' + where + ' LIMIT 1', val);
								else
									sqlite = db.exec('SELECT * FROM '+ param.table + ' LIMIT 1', val);
								break;
							default:
								if(where.length > 0)
									sqlite = db.exec('SELECT * FROM '+param.table+' WHERE ' + where, val);
								else
									sqlite = db.exec('SELECT * FROM '+param.table, []);
								break;
						}
						deferred.resolve(sqlite);
						deferred.reject('error');
					};
					http.send();
				}
				return deferred.promise;
			},
			service: function(method, param, callback){
				$ionicLoading.show({ content: 'Loading', animation: 'fade-in', showBackdrop: true, maxWidth: 200, showDelay: 0 });
				var config = {
					url: configs.restful_url + '/Restful/angular.html',
					cache: false,
					timeout: 30000,
				}
				switch(method.toLowerCase()){
					case 'get':
					case 'delete':
						config.method = method.toLowerCase();
						config.params = param;
						break;
					case 'post':
					case 'put':
					default:
						config.method = method.toLowerCase();
						config.data = param;
				}
				if (!unit.isEmptyObject(param.data)) {
					var device = JSON.parse($window.localStorage.getItem("device"));
					if(typeof param.data == 'object')
						param.data.uuid = device.uuid;
					else
						param.data = {uuid: device.uuid}
					param.data = JSON.stringify(param.data);
				}
				return $http(config).success(function(resp){
					$ionicLoading.hide();
					if(resp.type == 'Success'){
						if (!unit.isEmptyObject(resp.localStorage)){
							if(typeof resp.localStorage == 'object'){
								for (var p in resp.localStorage) {
									if(typeof resp.localStorage[p] == 'string' && resp.localStorage[p] == 'empty'){
										$window.localStorage.removeItem(p);
									}else{
										if(p == 'device'){
											var device = JSON.parse($window.localStorage.getItem("device"));
											var local = angular.extend(device, resp.localStorage[p]);
										}else{
											var local = resp.localStorage[p];
										}
										$window.localStorage.setItem(p, (typeof local == 'object') ? JSON.stringify(local) : local);
									}
								}
							}
						}
						if (!unit.isEmptyObject(resp.sessionStorage)){
							if(typeof resp.sessionStorage == 'object'){
								for (var p in resp.sessionStorage) {
									if(typeof resp.sessionStorage[p] == 'string' && resp.sessionStorage[p] == 'empty'){
										$window.sessionStorage.removeItem(p);
									}else{
										var session = resp.sessionStorage[p];
										$window.sessionStorage.setItem(p, (typeof session == 'object') ? JSON.stringify(session) : session);
									}
								}
							}
						}
					}
					if(method.toLowerCase() == 'post'){
						ngSwal.alert({
							text: resp.msg, 
							type: resp.type.toLowerCase(), 
							closeOnConfirm: true,
							confirmButtonText: '确定',
							showCancelButton: false,
						},function(){
							if(typeof(callback) == 'function') callback(resp);
						});
					}else{
						if(typeof(callback) == 'function') callback(resp);
					}
				});
			},
			userState: function(rule, callback, alert){
				"验证用户现在状态";
				var config = {jump: false}
				if(unit.isEmptyObject(alert)) alert = false;
				if(unit.isEmptyObject($window.localStorage.getItem('userInfo'))){
					var user = false;
				}else{
					var user = JSON.parse($window.localStorage.getItem('userInfo'));
				}
				var identity = {
					isLogin: (!user || unit.isEmptyObject(user.mobile))?false:true,
					isRealname: (!user || unit.isEmptyObject(user.is_realname) || user.is_realname == 0)?false:true,
					isBindweixin: (!user || unit.isEmptyObject(user.is_bindweixin) || user.is_bindweixin == 0)?false:true,
					isBindweibo: (!user || unit.isEmptyObject(user.is_bindweibo) || user.is_bindweibo == 0)?false:true,
					isBindqq: (!user || unit.isEmptyObject(user.is_bindqq) || user.is_bindqq == 0)?false:true,
					isEngineer: (!user || unit.isEmptyObject(user.is_engineer) || user.is_engineer == 0)?false:true,
				}
				if(!identity.isLogin)
					user = {headimg: 'img/no-astar.jpg'};
				switch(rule){
					case 'login':
						if(!identity.isLogin){
							config = {
								jump: true,
								text: '您尚未注册或登录！',
								button: '现在登录',
								to: 'app.login'
							}
						}
						break;
					case 'register':
						if(!identity.isLogin){
							config = {
								jump: true,
								text: '您尚未注册或登录！',
								button: '现在登录',
								to: 'app.login'
							}
						}
						break;
					case 'realname':
						if(!identity.isLogin){
							config = {
								jump: true,
								text: '您尚未注册或登录！',
								button: '现在登录',
								to: 'app.login'
							}
						}else{
							if(!identity.isRealname){
								config = {
									jump: true,
									text: '您尚未进行实名认证！',
									button: '现在申请',
									to: 'app.realname'
								}
							}else{
								if(user.is_realname == 1){
									config = {
										jump: true,
										text: '您的实名认证正在审核中！',
										button: '等待审核',
										to: 'app.my'
									}
								}
							}
						}
						break;
					case 'engineer':
						if(!identity.isLogin){
							config = {
								jump: true,
								text: '您尚未注册或登录！',
								button: '现在登录',
								to: 'app.login'
							}
						}else{
							if(!identity.isRealname){
								config = {
									jump: true,
									text: '您尚未进行实名认证！',
									button: '现在申请',
									to: 'app.apply-realname'
								}
							}else{
								if(!identity.isEngineer){
									config = {
										jump: true,
										text: '您尚未进行工程师认证！',
										button: '现在申请',
										to: 'app.apply-engineer'
									}
								}else{
									if(user.is_engineer == 1){
										config = {
											jump: true,
											text: '您的工程师认证正在审核中！',
											button: '等待审核',
											to: 'app.my'
										}
									}
								}
							}
						}
						break;
					case 'bindweixin':
						if(!identity.isLogin){
							config = {
								jump: true,
								text: '您尚未注册或登录！',
								button: '现在登录',
								to: 'app.login'
							}
						}else{
							if(!identity.isBindweixin){
								config = {
									jump: true,
									text: '您尚未绑定微信！',
									button: '现在绑定',
									to: 'app.bindweixin'
								}
							}
						}
						break;
					case 'bindweibo':
						if(!identity.isLogin){
							config = {
								jump: true,
								text: '您尚未注册或登录！',
								button: '现在登录',
								to: 'app.login'
							}
						}else{
							if(!identity.isBindweibo){
								config = {
									jump: true,
									text: '您尚未绑定微博！',
									button: '现在绑定',
									to: 'app.bindweibo'
								}
							}
						}
						break;
					case 'bindqq':
						if(!identity.isLogin){
							config = {
								jump: true,
								text: '您尚未注册或登录！',
								button: '现在登录',
								to: 'app.login'
							}
						}else {
							if (!identity.isBindqq) {
								config = {
									jump: true,
									text: '您尚未绑定QQ！',
									button: '现在绑定',
									to: 'app.bindqq'
								}
							}
						}
						break;
					case 'list':
						config = { jump: false};
				}
				if(config.jump){
					if(alert){
						ngSwal.confirm({text: config.text, type: "warning", confirmButtonText: config.button, cancelButtonText: "返回首页"},
							function(){
								$state.go(config.to, {}, {reload: true});
							}, function(){
								$state.go("app.home", {}, { reload: true });
							});
					}else{
						if(typeof(callback) == 'function') callback(user, identity);
					}
				}else{
					if(typeof(callback) == 'function') callback(user, identity);
				}
			},
			getStorage: function(){
				var Storage = {
					category: $window.localStorage.category,
					sitedate: $window.localStorage.sitedate,
					userInfo: $window.localStorage.userInfo
				}
				if(unit.isEmptyObject(Storage.category) || unit.isEmptyObject(Storage.sitedate) || unit.isEmptyObject(Storage.userInfo)){
					var checkData = {}
					if(!unit.isEmptyObject(Storage.category)){
						var category = JSON.parse(Storage.category);
						checkData.category = {md5: category.md5, sha1: category.sha1};
					}
					if(!unit.isEmptyObject(Storage.sitedate)){
						var sitedate = JSON.parse(Storage.sitedate);
						checkData.sitedate = {md5: sitedate.md5, sha1: sitedate.sha1};
					}
					if(!unit.isEmptyObject(Storage.userInfo)){
						var userInfo = JSON.parse(Storage.userInfo);
						checkData.userInfo = {uid: userInfo.uid, uuid: userInfo.uuid};
					}
					$http({
						url: configs.restful_url + '/Restful/angular.html',
						cache: false,
						timeout: 30000,
						method: 'get',
						params: {action: 'Restful', module: 'getCacheData', data: checkData}
					}).success(function(resp){
						if(resp.type == 'Success'){
							if(!unit.isEmptyObject(resp.sessionStorage)){
								for (var p in resp.sessionStorage) {
									if(typeof resp.sessionStorage[p] == 'string' && resp.sessionStorage[p] == 'empty'){
										$window.sessionStorage.removeItem(p);
									}else {
										var local = resp.sessionStorage[p];
										$window.sessionStorage.setItem(p, (typeof local == 'object') ? JSON.stringify(local) : local);
									}
								}
							}
							if(!unit.isEmptyObject(resp.localStorage)){
								for (var p in resp.localStorage) {
									var local = resp.localStorage[p];
									$window.localStorage.setItem(p, (typeof local == 'object') ? JSON.stringify(local) : local);
								}
							}
							
						}
					});
				}
				var device = $window.localStorage.device;
				var user = $window.localStorage.userInfo;
				var category = $window.localStorage.category;
				var sitedate = $window.localStorage.sitedate;
				return {
					device: (unit.isEmptyObject(device))?null:JSON.parse(device),
					user: (unit.isEmptyObject(user))?null:JSON.parse(user),
					category: (unit.isEmptyObject(category))?null:JSON.parse(category),
					sitedate: (unit.isEmptyObject(sitedate))?null:JSON.parse(sitedate)
				};
			}
		}
	})
	.factory('Service', function ($state, $ionicLoading, $window, xhr, unit, ngSwal) {
		return {
			bindWeixin: function(){
				Wechat.isInstalled(function(installed){
					WEIXININSTALL=installed;
					var scope = "snsapi_userinfo",
						state = "_" + (+new Date());
					Wechat.auth(scope, state, function (response) {
						xhr.service('post',{model: 'MustachUser', module: 'bindWeixin', data: response}, function(res){
							ngSwal.alert({type: 'success', text: res.content}, function(){
								$state.go('app.my');
							});
						});
					}, function (reason) {
						ngSwal.alert({type: 'error', text: "Auth Failed: " + reason});
					});
				}, function (reason) {
					ngSwal.alert({type: 'error', text: "Install Failed: " + reason});
				});
			},
			weixinLogin: function () {
				Wechat.isInstalled(function(installed){
					WEIXININSTALL = installed;
					var weixinLogin = installed,
						scope = "snsapi_userinfo",
						state = "_" + (+new Date());
					Wechat.auth(scope, state, function(response) {
						console.log(response);
						$ionicLoading.show({ content: 'Loading', animation: 'fade-in', showBackdrop: true, maxWidth: 200, showDelay: 0 });
						xhr.service('post', {model: 'MustachUser', module: 'weixinLogin', data: response}, function(res){
							console.log(res);
							$ionicLoading.hide();
							if(res.type == 'Info'){
								$window.sessionStorage.setItem('weixin', JSON.stringify(res.data));
								ngSwal.confirm({
									text: '您的微信未绑定胡子用户!?',
									title: '微信登录提示',
									confirmButtonText: '绑定现有用户',
									cancelButtonText: '创建新的用户'
								}, function(){
									$state.go('app.login');
								}, function () {
									$state.go('app.register');
								})
							}else{
								$state.go('app.my');
							}
						});
					}, function(reason){
						ngSwal.alert({text: "Auth Failed: " + reason});
					});
				}, function(reason){
					ngSwal.alert({text: "Install Failed: " + reason});
				});
			},
			sendSms: function(param, callback){
				"获取电信能力平台验证短信";
				$ionicLoading.show({ content: 'Loading', animation: 'fade-in', showBackdrop: true, maxWidth: 200, showDelay: 0 });
				xhr.service('post', {model: 'MustachUser', module: 'sendSmsCode', data: {
					type: 'ctc',
					mobile: param.mobile,
					action: unit.isEmptyObject(param.action)?'register':param.action,
				}}, function(resp){
					$ionicLoading.hide();
					ngSwal.alert({text: resp.msg, type: resp.type.toLowerCase(), timer: 3000});
					if(typeof(callback) == 'function') callback(resp);
				});
			},
			logout: function (back, callback) {
				ngSwal.confirm({
					type: "warning",
					text: "请确认：您真的要退出APP吗？",
					confirmButtonText: "是的，立即退出",
					closeOnConfirm: false
				},function(){
					ngSwal.close();
					xhr.service('post', {model: 'MustachUser', module: 'logout', data: {uuid : null}}, function(resp){
						if(resp.type == 'Success'){
							var storage = xhr.getStorage();
							delete storage.device.mobile;
							$window.localStorage.setItem('device', JSON.stringify(storage.device));
							$window.sessionStorage.removeItem('userInfo');
							$window.localStorage.removeItem('userInfo');
							xhr.userState('list', function(user, identity){
								if(typeof(callback) == 'function') callback(user, identity);
							});
							$state.go(back, {}, { reload: true });
						}
					});
				});
			},
			setInitialRun: function (initial) {
				$window.localStorage.setItem("initialRun", (initial ? "true" : "false"));
			},
			isInitialRun: function () {
				var value = $window.localStorage.getItem("initialRun") || "true";
				return value == "true";
			}
		}
	})
	.factory('Tasks', function () {
		var tasks = [{
			id: 0,
			name: '西城工程',
			pushtime: '2016-11-16 09:12:30',
			area: '32平方',
			tel:'138****4784',
			housetype:'三室两厅',
			categra:'新房验收',
			amount:'3万',
			progress:'验收已完成',
			address:'昆明市盘龙区盘龙小学',
			headface:'img/ben.png',
			headname:'张三',
			firstpic: 'img/task/task1.jpg',
			info:'设计师把有限的空间利用率达到最大化,将新古典石膏线条,dgyysaws，卫生间采用模块化配置,几何构造的轮廓,的线条装饰,明亮的色彩对比,展现了华夏蓝筹'
		}, {
			id: 1,
			name:'小西街',
			pushtime: '2016-11-15 21:05:32',
			tel:'136****8686',
			area: '62平方',
			housetype:'三室两厅',
			categra:'材料验收',
			amount:'工程金额',
			progress:'验收中',
			address:'昆明市盘龙区盘龙小学',
			headface:'img/max.jpg',
			headname:'李四',
			firstpic: 'img/task/task2.jpg',
			info:'设计师把有限的空间利用率达到最大化,将新古典石膏线条,dgyysaws，卫生间采用模块化配置,几何构造的轮廓,的线条装饰,明亮的色彩对比,展现了华夏蓝筹'
		}, {
			id: 2,
			name:'高新一小',
			pushtime: '2016-11-15 16:33:30',
			tel:'151****4475',
			area: '32平方',
			housetype:'三室两厅',
			categra:'竣工验收',
			amount:'4.8万',
			progress:'竣工已完成',
			address:'昆明市盘龙区盘龙小学',
			headface:'img/max.png',
			headname:'王麻子',
			firstpic: 'img/task/task3.png',
			info:'设计师把有限的空间利用率达到最大化,将新古典石膏线条,dgyysaws，卫生间采用模块化配置,几何构造的轮廓,的线条装饰,明亮的色彩对比,展现了华夏蓝筹'
		}, {
			id: 3,
			name:'大四方新化街',
			pushtime: '2016-11-15 12:58:30',
			tel:'133****6869',
			area: '88平方',
			housetype:'三室两厅',
			categra:'结算审查',
			amount:'8.5万',
			progress:'结算中',
			address:'昆明市盘龙区盘龙小学',
			headface:'img/mcfly.jpg',
			headname:'张五常',
			firstpic: 'img/task/task4.png',
			info:'设计师把有限的空间利用率达到最大化,将新古典石膏线条,dgyysaws，卫生间采用模块化配置,几何构造的轮廓,的线条装饰,明亮的色彩对比,展现了华夏蓝筹'
		}, {
			id: 4,
			name:'小西街',
			pushtime: '2016-11-14 11:44:30',
			tel:'158****5896',
			area: '96平方',
			housetype:'三室两厅',
			categra:'环境监测',
			amount:'6.6万',
			progress:'监测良好',
			address:'昆明市盘龙区盘龙小学',
			headface:'img/perry.png',
			headname:'李小龙',
			firstpic: 'img/task/task1.jpg',
			info:'设计师把有限的空间利用率达到最大化,将新古典石膏线条,dgyysaws，卫生间采用模块化配置,几何构造的轮廓,的线条装饰,明亮的色彩对比,展现了华夏蓝筹'
		}, {
			id: 5,
			name:'新平小小里',
			pushtime: '2016-11-14 10:12:30',
			tel:'147****8836',
			area: '132平方',
			housetype:'三室两厅',
			categra:'设计咨询',
			amount:'7.5万',
			progress:'设计满意',
			address:'昆明市盘龙区盘龙小学',
			headface:'img/ciffee.png',
			headname:'王勃',
			firstpic: 'img/task/task1.jpg',
			info:'设计师把有限的空间利用率达到最大化,将新古典石膏线条,dgyysaws，卫生间采用模块化配置,几何构造的轮廓,的线条装饰,明亮的色彩对比,展现了华夏蓝筹'
		}, {
			id: 6,
			name:'家家道小区',
			pushtime: '2016-11-13 17:12:30',
			tel:'133****2423',
			area: '122平方',
			housetype:'三室两厅',
			categra:'水电工程验收',
			amount:'9.2万',
			progress:'水电不合格',
			address:'昆明市盘龙区盘龙小学',
			headface:'img/ionic.png',
			headname:'李雪',
			firstpic: 'img/task/task1.jpg',
			info:'设计师把有限的空间利用率达到最大化,将新古典石膏线条,dgyysaws，卫生间采用模块化配置,几何构造的轮廓,的线条装饰,明亮的色彩对比,展现了华夏蓝筹'
		},  {
			id: 14,
			name:'新北门七十二家',
			pushtime: '2016-11-13 11:12:30',
			tel:'147****8385',
			area: '167平方',
			housetype:'三室两厅',
			categra:'新房验收',
			amount:'13万',
			progress:'三期已完成',
			address:'昆明市盘龙区盘龙小学',
			headface:'img/ben.png',
			headname:'王雷',
			firstpic: 'img/task/task1.jpg',
			info:'设计师把有限的空间利用率达到最大化,将新古典石膏线条,dgyysaws，卫生间采用模块化配置,几何构造的轮廓,的线条装饰,明亮的色彩对比,展现了华夏蓝筹'
		}, {
			id: 14,
			name:'新北门七十五家',
			pushtime: '2016-11-12 14:12:30',
			tel:'135****4567',
			area: '167平方',
			housetype:'三室两厅',
			categra:'新房验收',
			amount:'13万',
			progress:'三期已完成',
			address:'昆明市盘龙区盘龙小学',
			headface:'img/ben.png',
			headname:'王雷',
			firstpic: 'img/task/task1.jpg',
			info:'设计师把有限的空间利用率达到最大化,将新古典石膏线条,dgyysaws，卫生间采用模块化配置,几何构造的轮廓,的线条装饰,明亮的色彩对比,展现了华夏蓝筹'
		},{
			id: 14,
			name:'新北门七十七家',
			pushtime: '2016-11-11 11:46:30',
			tel:'134****5527',
			area: '167平方',
			housetype:'三室两厅',
			categra:'新房验收',
			amount:'13万',
			progress:'三期已完成',
			address:'昆明市盘龙区盘龙小学',
			headface:'img/ben.png',
			headname:'王雷',
			firstpic: 'img/task/task1.jpg',
			info:'设计师把有限的空间利用率达到最大化,将新古典石膏线条,dgyysaws，卫生间采用模块化配置,几何构造的轮廓,的线条装饰,明亮的色彩对比,展现了华夏蓝筹'
		}];
		return {
			all: function () {
				return tasks;
			},
			get: function (taskId) {
				for (var i = 0; i < tasks.length; i++) {
					if (tasks[i].id === parseInt(taskId)) {
						return tasks[i];
					}
				}
				return null;
			}
		};
	})
	.factory('Engineers', function () {
		var engineers = [{
			id: 0,
			describe: '环境监测 二级工程师',
			image:'img/engineer/engineer1.jpg',
			name:'李三',
			workage:'10年',
			score:'7分',
			goodat:'环境监测',
			intro: '毕业于西安交通大学,擅长风格欧式,简约李全,毕业于西安交通大学,擅长风格欧式,简约 更多',
			star:'<i class="iconfont f10 color-energized">&#xe646;</i>'
		}, {
			id: 1,
			describe: '水电监测 二级工程师',
			image:'img/engineer/engineer2.jpg',
			name:'张三',
			workage:'8年',
			score:'8.5分',
			goodat:'新房测量',
			intro: '毕业于西安交通大学,擅长风格欧式,简约李全,毕业于西安交通大学,擅长风格欧式,简约 更多',
			star:'<i class="iconfont f10 color-energized">&#xe646;</i>'
		}, {
			id: 2,
			describe: '新房测量 一级工程师',
			image:'img/engineer/engineer3.jpg',
			name:'十兵卫',
			workage:'3年',
			score:'8分',
			goodat:'设计咨询',
			intro: '毕业于西安交通大学,擅长风格欧式,简约李全,毕业于西安交通大学,擅长风格欧式,简约 更多',
			star:'<i class="iconfont f10 color-energized">&#xe646;</i>'
		}, {
			id: 3,
			describe: '过程监理 二级工程师',
			image:'img/engineer/engineer4.jpg',
			name:'王七',
			workage:'6年',
			score:'7.7分',
			goodat:'全程咨询',
			intro: '毕业于西安交通大学,擅长风格欧式,简约李全,毕业于西安交通大学,擅长风格欧式,简约 更多',
			star:'<i class="iconfont f10 color-energized">&#xe646;</i>'
		}, {
			id: 4,
			describe: '设计咨询 一级工程师',
			image:'img/engineer/engineer5.jpg',
			name:'季九',
			workage:'10年',
			score:'8.8分',
			goodat:'现场核量',
			intro: '毕业于西安交通大学,擅长风格欧式,简约李全,毕业于西安交通大学,擅长风格欧式,简约 更多',
			star:'<i class="iconfont f10 color-energized">&#xe646;</i>'
		}, {
			id: 5,
			describe: '环境监测 二级工程师',
			image:'img/engineer/engineer6.jpg',
			name:'张大胖',
			workage:'4年',
			score:'7分',
			goodat:'环境监测',
			intro: '毕业于西安交通大学,擅长风格欧式,简约李全,毕业于西安交通大学,擅长风格欧式,简约 更多',
			star:'<i class="iconfont f10 color-energized">&#xe646;</i>'
		}, {
			id: 6,
			describe: '水电监测 二级工程师',
			image:'img/engineer/engineer7.jpg',
			name:'张三', score:'8.5分',
			goodat:'新房测量',
			star:'<i class="iconfont f10 color-energized">&#xe646;</i>'
		}, {
			id: 7,
			describe: '新房测量 一级工程师',
			image:'img/engineer/engineer8.jpg',
			name:'田小天',
			workage:'2年',
			score:'8分',
			goodat:'设计咨询',
			intro: '毕业于西安交通大学,擅长风格欧式,简约李全,毕业于西安交通大学,擅长风格欧式,简约 更多',
			star:'<i class="iconfont f10 color-energized">&#xe646;</i>'
		}, {
			id: 8,
			describe: '过程监理 二级工程师',
			image:'img/engineer/engineer9.jpg',
			name:'李肖肖',
			workage:'10年',
			score:'7.7分',
			goodat:'全程咨询',
			intro: '毕业于西安交通大学,擅长风格欧式,简约李全,毕业于西安交通大学,擅长风格欧式,简约 更多',
			star:'<i class="iconfont f10 color-energized">&#xe646;</i>'
		}, {
			id: 9,
			describe: '过程监理 二级工程师',
			image:'img/engineer/engineer10.jpg',
			name:'王七',
			workage:'5年',
			score:'7.7分',
			goodat:'全程咨询',
			intro: '毕业于西安交通大学,擅长风格欧式,简约李全,毕业于西安交通大学,擅长风格欧式,简约 更多',
			star:'<i class="iconfont f10 color-energized">&#xe646;</i>'
		}, {
			id: 10,
			describe: '设计咨询 一级工程师',
			image:'img/engineer/engineer11.jpg',
			name:'季九',
			workage:'3年',
			score:'8.8分',
			goodat:'现场核量',
			intro: '毕业于西安交通大学,擅长风格欧式,简约李全,毕业于西安交通大学,擅长风格欧式,简约 更多',
			star:'<i class="iconfont f10 color-energized">&#xe646;</i>'
		}];
		return {
			all: function(){
				return engineers;
			},
			get: function(engineerId){
				for(var i = 0; i < engineers.length; i++){
					if(engineers[i].id === parseInt(engineerId)){
						return engineers[i];
					}
				}
				return null;
			}
		}
	})
	.factory('Categorizers', function(){
		var categorizers = [{
			id: 0,
			cate: '新房验收',
			sum:'有必要进行吗?'
		},{
			id: 1,
			cate: '预算审核',
			sum:'有必要进行吗?'
		},{
			id: 2,
			cate: '材料验收相',
			sum:'有必要进行吗?'
		},{
			id: 3,
			cate: '专业咨询',
			sum:'有必要进测吗?'
		},{
			id: 4,
			cate: '水电验收',
			sum:'水电进行检测吗?'
		},{
			id: 5,
			cate: '现场核量',
			sum:'有必要进行检吗?'
		},{
			id: 6,
			cate: '竣工验收',
			sum:'有必要进行检测吗?'
		},{
			id: 7,
			cate: '环境监测',
			sum:'有必要进行检测吗'
		},{
			id: 8,
			cate: '全过程监理',
			sum:'有必要进行检'
		},{
			id: 9,
			cate: '结算审查',
			sum:'有必要进行检测'
		},{
			id: 10,
			cate: '设计咨询',
			sum:'有必要进行检测吗'
		}];
		return{
			all: function(){
				return categorizers;
			},
			get: function(categorizerId){
				for(var i = 0; i < categorizers.length; i++){
					if(categorizers[i].id === parseInt(categorizerId)){
						return categorizers[i];
					}
				}
				return null;
			}
		}
	})
	.factory('Hotqustions', function(){
		var hotqustions = [{
			id: 0,
			qus: '冬天装修应该注意哪些问题',
			ans: '问题的解决办法问题的解决办法问题的解决办法问题的解决办法问题的解决办法问题的解决办法问题的解决办法问题的解决办法',
			pushtime: '2016-11-12 09:12:30'
		},{
			id: 1,
			qus: '装修前必须要知道的一点知识',
			ans: '西城工程问题的解决办法问题的解决办法问题的解决办法问题的解决办法问题的解决办法',
			pushtime: '2016-11-15 09:12:30'
		},{
			id: 2,
			qus: '哪种装修更适合你',
			ans: '西城工程问题的解决办法问题的解决办法问题的解决办法问题的解决办法问题的解决办法',
			pushtime: '2016-11-14 09:12:30'
		},{
			id: 3,
			qus: '装修完成后环境测量重要吗',
			ans: '西城工程问题的解决办法问题的解决办法问题的解决办法问题的解决办法问题的解决办法',
			pushtime: '2016-11-11 09:12:30'
		},{
			id: 4,
			qus: '水电改造要怎么注意',
			ans: '西城工程问题的解决办法问题的解决办法问题的解决办法问题的解决办法问题的解决办法',
			pushtime: '2016-11-11 09:12:30'
		}];
		return{
			all: function(){
				return hotqustions;
			},
			get: function(hotqustionId){
				for(var i = 0; i < hotqustions.length; i++){
					if(hotqustions[i].id === parseInt(hotqustionId)){
						return hotqustions[i];
					}
				}
				return null;
			}
		}
	});